package com.usian.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.usian.mapper.TbUserMapper;
import com.usian.pojo.TbUser;
import com.usian.redis.RedisClient;
import com.usian.service.SSOService;
import com.usian.utils.MD5Utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @author chen
 * @date 2021/1/21 - 20:07 - 星期四
 * @project usian_parent
 * @package com.usian.service.Impl
 * @by GGbomd猪猪侠
 */
/**
 * 用户注册与登录业务层
 */
@Service
@Transactional
public class SSOServiceImpl implements SSOService {

    @Autowired
    private TbUserMapper tbUserMapper;

    @Autowired
    private RedisClient redisClient;

    @Value("${USER_INFO}")
    private String USER_INFO;

    @Value("${SESSION_EXPIRE}")
    private long SESSION_EXPIRE;

    /**
     * 对用户的注册信息(用户名与电话号码)做数据校验
     * @param checkValue 用户名 和手机号
     * @param checkFlag
     * @return
     */
    @Override
    public boolean checkUserInfo(String checkValue, Integer checkFlag) {
        QueryWrapper<TbUser> queryWrapper = new QueryWrapper<>();
        // 1、查询条件根据参数动态生成：1、2分别代表username、phone
        if (checkFlag == 1){
            // 查询用户名 是否重复
            queryWrapper.eq("username",checkValue);
        }else if (checkFlag == 2){
            // 查询手机号是否重复
            queryWrapper.eq("phone",checkValue);
        }
        // 2、从tb_user表中查询数据
        List<TbUser> tbUsers = tbUserMapper.selectList(queryWrapper);
        // 3、判断查询结果，如果查询到数据返回false。
        if (tbUsers == null || tbUsers.size() == 0){
            // 4、如果没有返回true。
            return true;
        }
        // 5、如果有返回false。
        return false;
    }

    /**
     * 用户注册 相当于添加返回一条数据
     * @param tbUser
     * @return
     */
    @Override
    public Integer userRegister(TbUser tbUser) {
        //将密码做加密处理。
        String password = MD5Utils.digest(tbUser.getPassword());
        tbUser.setPassword(password);
        // 不起剩下的数据
        tbUser.setCreated(new Date());
        tbUser.setUpdated(new Date());
        return tbUserMapper.insertSelective(tbUser);
    }

    /**
     * u用户登录
     * @param username
     * @param password
     * @return
     */
    @Override
    public Map userLogin(String username, String password) {
        // 1、判断用户名密码是否正确。
        // 把密码装换成Md5 去和数据库的密码判断
        String pwd = MD5Utils.digest(password);
        QueryWrapper<TbUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username",username);
        queryWrapper.eq("password",pwd);
        TbUser tbUser = tbUserMapper.selectOne(queryWrapper);
        if (tbUser==null){
            return null;
        }
        // 2、登录成功后生成token。Token相当于原来的jsessionid，字符串，可以使用uuid。
        String token = UUID.randomUUID().toString();
        // 3、把用户信息保存到redis。Key就是token，value就是TbUser对象转换成json。
        redisClient.set(USER_INFO+":"+token,tbUser);
        // 5、设置key的过期时间。模拟Session的过期时间。
        redisClient.expire(USER_INFO+":"+token,SESSION_EXPIRE);

        //给前台返回的数据
        Map<String, Object> HashMap = new HashMap<>();
        HashMap.put("token",token);
        HashMap.put("userid",tbUser.getId());
        HashMap.put("username",tbUser.getUsername());
        return HashMap;
    }

    /**
     * 查询用户登录是否已经过期
     * @param token
     * @return
     */
    @Override
    public TbUser getUserByToken(String token) {
        TbUser tbUser = (TbUser) redisClient.get(USER_INFO+":"+token);
        if(tbUser!=null){
            //需要重置key的过期时间。
            redisClient.expire(USER_INFO+":"+token,SESSION_EXPIRE);
            return tbUser;
        }
        return null;
    }

    /**
     * 退出登录
     * @param token
     * @return
     */
    @Override
    public Boolean logOut(String token) {
        return redisClient.del(USER_INFO+":"+token);
    }
}
